﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Collections;
using System.Linq.Expressions;

namespace Distrackting.DataLayer
{
    public class BDPercursos
    {
        public static void actualizaPercurso(Guid cod_percurso, String nome, Guid lPartida, Guid lChegada, Double distancia, int duracao, Guid epoca, Guid ambito, Guid desnivel, Guid entidade, Guid estado, Guid dificuldade, Guid tipo, String descricao, DateTime data)
        {
            try
            {
                Percurso p = new Percurso();
                p.cod_percurso = cod_percurso;
                p.nome = nome;
                p.cod_partida = lPartida;
                p.distancia = distancia;
                p.duracao = duracao;
                p.cod_epoca = epoca;
                p.cod_ambito = ambito;
                p.cod_desnivel = desnivel;
                p.cod_chegada = lChegada;
                p.cod_entidade = entidade;
                p.cod_dificuldade = dificuldade;
                p.cod_tipo = tipo;
                p.descricao = descricao;
                p.data = data;
                dataPercurso.changePercurso(p);
            }
            catch (Exception) { throw new Exception("Não foi possível actualizar o percurso dado."); }


        }

        public static Hashtable getListaFichGPS()
        {
            try
            {
                List<Percurso> lperc = dataPercurso.getPercursos().ToList<Percurso>();
                Hashtable htperc = new Hashtable();

                foreach (Percurso p in lperc)
                {
                    htperc.Add(p.nome, p.cod_percurso);
                }

                return htperc;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<Ponto> getListaOrdenadaPontos(Guid cod_perc)
        {
            try
            {
                return dataPonto.getListaOrdenadaPontos(cod_perc).ToList();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void marcarPercorrido(Guid cod_user,Guid cod_perc)
        {
            try
            {
            Testemunho t = new Testemunho();
            t.cod_utilizador = cod_user;
            t.cod_percurso = cod_perc;
            dataTestemunho.createTestemunho(t);
            }
            catch (Exception e)
            {
            throw e;
            }
        }

        public static void createTestemunho(Guid cod_user, Guid cod_perc, String testemunho, int rating)
        {
            try
            {
                Testemunho t = new Testemunho();
                t.cod_percurso = cod_perc;
                t.cod_utilizador = cod_user;
                t.texto = testemunho;
                t.rating = rating;
                t.data_realizado = System.DateTime.Today;
                t.cod_testemunho = System.Guid.NewGuid();
                dataTestemunho.createTestemunho(t);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void adicionarTestemunho(Guid cod_user, Guid cod_perc, String testemunho, int rating)
        {
            try
            {   Testemunho t = dataTestemunho.getTestemunho(cod_user,cod_perc);
                t.texto = testemunho;
                t.rating = rating;
                t.data_realizado = System.DateTime.Today;
                dataTestemunho.changeTestemunho(t);
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        public static void adicionaFoto(Guid cod_ponto, String url, Guid cod_user, DateTime dt)
        {
            try
            {
                Foto f = new Foto();
                f.cod_ponto = cod_ponto;
                f.url = url;
                f.cod_utilizador = cod_user;
                f.data_hora = dt;
                dataFoto.createFoto(f);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void adicionaComentario(Guid cod_user, Guid cod_perc, String texto)
        {
            try
            {
                Comentario c = new Comentario();
                c.cod_utilizador = cod_user;
                c.cod_percurso = cod_perc;
                c.texto = texto;
                c.data = System.DateTime.Today;
                dataComentario.createComentario(c);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static Percurso getPercurso(Guid cod_perc)
        {
            try
            {
                Percurso p = dataPercurso.getPercurso(cod_perc);
                return p;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static IQueryable<Percurso> getPercPesquisa(String localidade, String dificuldade, String tipo, String ambito)
        {
            try
            {
                dbDataDataContext dbData = new dbDataDataContext();
                IQueryable<Percurso> lista = dbData.Percursos;

                if (localidade != "(nenhuma)") lista = (from p in lista
                                                        where p.Localidade1.nome == localidade
                                      select p);
                if (dificuldade != "(nenhuma)") lista = (from p in lista
                                                         where p.Dificuldade.descricao == dificuldade
                                      select p);
                if (tipo != "(nenhuma)") lista = (from p in lista
                                                  where p.Tipo_percurso.descricao == tipo
                                      select p);
                if (ambito != "(nenhuma)") lista = (from p in lista
                                                    where p.Ambito.descricao == ambito
                                      select p);
                return lista;
            }
            catch (Exception e)
            {
                throw e;
            }

        }


        

        public static List<Percurso> getListaPercursos()
        {
            try
            {
                List<Percurso> lperc = dataPercurso.getPercursos().ToList<Percurso>();
                return lperc;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<Percurso> getPercursos(Expression<Func<Percurso,Boolean>> whereClause)
        {
            try
            {
                List<Percurso> lperc = dataPercurso.getPercursos(whereClause).ToList();
                return lperc;
            }
            catch (Exception e)
            {
                throw e;
            }
        }


        public static List<Comentario> getComentariosByPercurso(Guid cod_perc)
        {
            try
            {
                Percurso p = dataPercurso.getPercurso(cod_perc);
                return p.Comentarios.ToList<Comentario>();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void apagaComentario(Guid cod_comentario)
        {
            try
            {
                Comentario c = dataComentario.getComentario(cod_comentario);
                dataComentario.deleteComentario(c);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void apagaTestemunho(Guid cod_testemunho)
        {
            try
            {
                Testemunho t = dataTestemunho.getTestemunho(cod_testemunho);
                dataTestemunho.deleteTestemunho(t);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void apagaFoto(String url)
        {
            try
            {
                Foto f = dataFoto.getFoto(url);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<Testemunho> getTestemunhosByPercurso(Guid cod_perc)
        {
            try
            {
                Percurso p = dataPercurso.getPercurso(cod_perc);
                return p.Testemunhos.ToList<Testemunho>();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<Foto> getFotosByUtilizador(Guid cod_user)
        {
            try
            {
                Utilizador u = dataUtilizador.getUtilizador(cod_user);
                return u.Fotos.ToList<Foto>();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<Comentario> getComentariosByUtilizador(Guid cod_user)
        {
            try
            {
                Utilizador u = dataUtilizador.getUtilizador(cod_user);
                return u.Comentarios.ToList<Comentario>();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

       
        public static List<Testemunho> getTestemunhosByUtilizador(Guid cod_user)
        {
            try
            {
                Utilizador u = dataUtilizador.getUtilizador(cod_user);
                return u.Testemunhos.ToList<Testemunho>();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<Foto> getFotosByPercurso(Guid cod_perc)
        {
            try
            {
                Percurso p = dataPercurso.getPercurso(cod_perc);
                List<Ponto> pontos = p.Pontos.ToList<Ponto>();
                List<Foto> lfotos = new List<Foto>();
                foreach (Ponto ponto in pontos)
                {
                    foreach (Foto f in ponto.Fotos.ToList<Foto>())
                    {
                        lfotos.Add(f);
                    }
                }
                return lfotos;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void setListaPontos(List<Ponto> pontos)
        {
            try
            {
                foreach (Ponto p in pontos)
                {
                    dataPonto.changePonto(p);
                }
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void apagaPercurso(Guid cod_perc) //FIX ME!!!!!!!
        {
            try
            {
                Percurso p = dataPercurso.getPercurso(cod_perc);
                dataPercurso.deletePercurso(p);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static Guid criaPercurso(String nome, Guid cod_utilizador, Guid cod_partida, Guid cod_chegada, float dist, int duracao, Guid epoca, Guid ambito, Guid desnivel, Guid entidade, Guid dificuldade, Guid tipo, String descricao, DateTime data , List<Ponto> lista_pts)
        {
            try
            {

                Percurso p = new Percurso();
                p.descarregado = 0;
                p.nome = nome;
                p.cod_partida = cod_partida;
                p.distancia = dist;
                p.duracao = duracao;
                p.cod_epoca = epoca;
                p.cod_ambito = ambito;
                p.cod_desnivel = desnivel;
                p.cod_chegada = cod_chegada;
                p.cod_entidade = entidade;
                p.cod_estado = new Guid("7936c081-8469-4103-a964-c65dcc8d283b");//FIX ME -> guid está mal!!!!!!!!!!
                p.cod_dificuldade = dificuldade;
                p.cod_tipo = tipo;
                p.descricao = descricao;
                p.data = data;
                p.rating_total = 0;
                p.cod_utilizador = cod_utilizador;
                return dataPercurso.createPercurso(p, lista_pts);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void marcarPercursoDebaixoOlho(Guid cod_perc, Guid cod_user)
        {
            try
            {
                Percurso_realizar p = new Percurso_realizar();
                p.cod_percurso = cod_perc;
                p.cod_utilizador = cod_user;
                dataPercurso_realizar.createPercurso_realizar(p);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void desmarcarPercursoDebaixoOlho(Guid cod_perc, Guid cod_user)
        {
            try
            {
                Percurso_realizar p = dataPercurso_realizar.getPercurso_realizar(cod_user, cod_perc);
                if(p!=null) dataPercurso_realizar.deletePercurso_realizar(p);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static bool verificaMarcadoDebaixoDOlho(Guid cod_perc, Guid cod_user)
        {
            try
            {
                dbDataDataContext dbData = new dbDataDataContext();
                Percurso_realizar pr = (from p in dbData.Percurso_realizars
                                        where p.cod_percurso == cod_perc && p.cod_utilizador == cod_user
                                        select p).FirstOrDefault();

                if (pr == null) return false;
                return true;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static Double getClassificacao(Guid cod_perc)
        {
            try
            {
                Percurso p = dataPercurso.getPercurso(cod_perc);
                return Convert.ToDouble(p.rating_total);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static void actualizaClassificacao(Guid cod_perc)
        {
            try
            {
                int rates = 0, i = 0;

                Percurso p = dataPercurso.getPercurso(cod_perc);
                foreach (Testemunho t in p.Testemunhos)
                {
                    rates += Convert.ToInt32(t.rating);
                    i++;
                }
                p.rating_total = rates / i;
                dataPercurso.changePercurso(p);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static bool verificaPercorrido(Guid cod_perc, Guid cod_user)
        {
            try
            {
                dbDataDataContext dbData = new dbDataDataContext();
                Testemunho test = (from t in dbData.Testemunhos
                                   where t.cod_percurso == cod_perc && t.cod_utilizador == cod_user
                                   select t).FirstOrDefault();

                if (test == null) return false;
                return true;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        
    }
}
